﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using NL.ADA.Common;
using NL.ADA.Logging;

namespace NL.ADA.NotificationService
{
    // NOTE: If you change the class name "NotificationService" here, you must also update the reference to "NotificationService" in Web.config and in the associated .svc file.
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Single)]
    public class NotificationService : INotificationService
    {
        private static readonly AdaLogger _logger = new AdaLogger();

        private static readonly Dictionary<string, INotificationServiceCallBack> _subscribers =
            new Dictionary<string, INotificationServiceCallBack>();
        #region INotificationService Members

        public void NotifyServerModified(DateTime modified)
        {
            _logger.Log(LogEvent.EnterEvent);
            if (_subscribers.Count > 0)
            {
                _logger.Log(LogEvent.InfoEvent, string.Format("subscribers count: {0}", _subscribers.Count));
                foreach (KeyValuePair<string,INotificationServiceCallBack> notify in _subscribers)
                //_subscribers.ForEach(delegate(INotificationServiceCallBack notify)
                {
                    if (((ICommunicationObject)notify.Value).State == CommunicationState.Opened)
                    {
                        _logger.Log(LogEvent.InfoEvent, string.Format("notify client"));
                        notify.Value.ServerModified(modified);
                        _logger.Log(LogEvent.InfoEvent, string.Format("client notified !"));
                    }
                    else
                    {
                        _subscribers.Remove(notify.Key);
                        _logger.Log(LogEvent.InfoEvent, string.Format("subscriber removed"));
                    }
                }
            }
            _logger.Log(LogEvent.InfoEvent, string.Format("subscribers count: {0} before leave event", _subscribers.Count));
            _logger.Log(LogEvent.LeaveEvent);
        }



        public bool Register(int appId,int modeId)
        {
            _logger.Log(LogEvent.EnterEvent);
            var result = false;
            var key = appId + "_" + modeId;
            _logger.Log(LogEvent.InfoEvent,"register for key"+ key);
            try
            {
                var callBack = OperationContext.Current.GetCallbackChannel<INotificationServiceCallBack>();
                _logger.Log(LogEvent.InfoEvent, string.Format("subscribers count: {0}",_subscribers.Count));
                if (!_subscribers.Keys.Contains(key))
                {
                    _logger.Log(LogEvent.InfoEvent, "subscribers do not contain callback");
                    _subscribers.Add(key,callBack);
                    _logger.Log(LogEvent.InfoEvent, "subscriber has been added to list");
                }
                _logger.Log(LogEvent.InfoEvent, string.Format("subscribers count: {0}", _subscribers.Count));
                result = true;

            }
            catch (Exception ex)
            {
                _logger.Log(LogEvent.InfoEvent, ex.Message);
                result = false;

            }
            _logger.Log(LogEvent.LeaveEvent);
            return result;
        }

        public bool UnRegister(int appId, int modeId)
        {
            _logger.Log(LogEvent.EnterEvent);
            var key = appId + "_" + modeId;
            _logger.Log(LogEvent.InfoEvent, "unregister for key" + key);
            var result = false;
            try
            {
                var callBack = OperationContext.Current.GetCallbackChannel<INotificationServiceCallBack>();
                _logger.Log(LogEvent.InfoEvent, string.Format("subscribers count: {0}", _subscribers.Count));
                if (_subscribers.Keys.Contains(key))
                {
                    _subscribers.Remove(key);
                    _logger.Log(LogEvent.InfoEvent,"subscriber has been removed form the list");
                }
                _logger.Log(LogEvent.InfoEvent, string.Format("subscribers count: {0}", _subscribers.Count));
                result = true;
            }
            catch (Exception ex)
            {
                _logger.Log(LogEvent.ErrorEvent, ex);
                result = false;
            }
            _logger.Log(LogEvent.LeaveEvent);
            return result;
        }

        #endregion
    }
}
